// MegaSlider.cpp : implementation file
//

#include "stdafx.h"
#include "MegaSlider.h"
#include "bmp2rgn.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CMegaSlider

CMegaSlider::CMegaSlider()
{
	m_pLeftBmp = m_pRightBmp = m_pCursorBmp = NULL;
	m_nMin = 0;
	m_nMax = 100;
	m_nPos = 50;
	m_bDrag = false;

	m_pOldBackBmp = NULL;
}

CMegaSlider::~CMegaSlider()
{
	if(m_pOldBackBmp)
		m_dcBack.SelectObject(m_pOldBackBmp);

	if(m_pLeftBmp)	delete m_pLeftBmp;
	if(m_pRightBmp)	delete m_pRightBmp;
	if(m_pCursorBmp)delete m_pCursorBmp;
}


BEGIN_MESSAGE_MAP(CMegaSlider, CWnd)
	//{{AFX_MSG_MAP(CMegaSlider)
	ON_WM_PAINT()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_ERASEBKGND()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

void CMegaSlider::SetBitmaps(UINT uiLeft, UINT uiRight, UINT uiCursor)
{
	m_pLeftBmp = new CMegaBitmap();
	m_pRightBmp = new CMegaBitmap();
	m_pCursorBmp = new CMegaBitmap();

	m_pLeftBmp->LoadBitmap(uiLeft);
	m_pRightBmp->LoadBitmap(uiRight);
	m_pCursorBmp->LoadBitmap(uiCursor);

	CSize sz = m_pLeftBmp->GetBitmapDimension();
	SetWindowPos(NULL, 0, 0, sz.cx, sz.cy, SWP_NOZORDER|SWP_NOMOVE);

	RedrawWindow();
}

void CMegaSlider::SetBackgroundBmp(CMegaBitmap * pBack)
{
	// copy parent's background into internal DC
	// do it only once
	CWnd * pParent = GetParent();
	CClientDC ParentDC(pParent);
	CDC TmpDC;
	TmpDC.CreateCompatibleDC(&ParentDC);
	CGdiObject * pOldBmp = TmpDC.SelectObject(pBack);

	m_dcBack.CreateCompatibleDC(&ParentDC);

	CRect rcw;
	GetWindowRect(&rcw);
	GetParent()->ScreenToClient(&rcw);
	m_BackBmp.CreateCompatibleBitmap(&ParentDC, rcw.Width(), rcw.Height());
	m_pOldBackBmp = m_dcBack.SelectObject(&m_BackBmp);
	m_dcBack.BitBlt(0, 0, rcw.Width(), rcw.Height(), &TmpDC, rcw.left, rcw.top, SRCCOPY);

	TmpDC.SelectObject(pOldBmp);
}

void CMegaSlider::SetRange(int nMin, int nMax)
{
	SetScrollRange(nMin, nMax);
}
void CMegaSlider::SetScrollRange(int nMin, int nMax)
{
	m_nMin = nMin;
	m_nMax = nMax;

	RedrawWindow();
}

void CMegaSlider::SetPos(int nPos)
{
	SetScrollPos(nPos);
}
void CMegaSlider::SetScrollPos(int nPos)
{
	m_nPos = nPos;
	if(m_nPos > m_nMax) m_nPos = m_nMax;
	if(m_nPos < m_nMin) m_nPos = m_nMin;

	GetParent()->SendMessage(WM_HSCROLL, SB_THUMBTRACK, (LPARAM) GetSafeHwnd());

	RedrawWindow();
}

void CMegaSlider::GetRange(int& min, int& max)
{
	min = m_nMin;
	max = m_nMax;
}
void CMegaSlider::GetScrollRange(int * pMin, int * pMax)
{
	*pMin = m_nMin;
	*pMax = m_nMax;
}

int CMegaSlider::GetPos()
{
	return m_nPos;
}
int CMegaSlider::GetScrollPos()
{
	return m_nPos;
}

/////////////////////////////////////////////////////////////////////////////
// CMegaSlider message handlers
void CMegaSlider::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	
	// TODO: Add your message handler code here
	int nVal = GetScrollPos();
	int nMin = 0, nMax = 0;
	GetScrollRange(&nMin, &nMax);
	int nRange = nMax-nMin;

	CRect rc;
	GetClientRect(&rc);
	int w = rc.Width();
	int h = rc.Height();

	CRect rcw;
	GetWindowRect(&rcw);
	GetParent()->ScreenToClient(&rcw);

	if(m_pLeftBmp && m_pRightBmp && m_pCursorBmp)
	{
		CDC MemDC;
		MemDC.CreateCompatibleDC(&dc);
		CBitmap bmp;
		bmp.CreateCompatibleBitmap(&dc, w, h);
		CGdiObject * pOldBmp = MemDC.SelectObject(&bmp);

		// copy parent's background first
		MemDC.BitBlt(0, 0, w, h, &m_dcBack, 0, 0, SRCCOPY);

		int nLeft = nVal*w / nRange;
		CSize sz = m_pCursorBmp->GetBitmapDimension();
		int nCursorPos = nLeft-sz.cx/2;
		if(nCursorPos < 0) nCursorPos = 0;
		if(nCursorPos > w-sz.cx) nCursorPos = w-sz.cx;

		DrawTransparentBitmap(&MemDC, m_pRightBmp, 0, 0, w, h, RGB(255, 0, 0));
		DrawTransparentBitmap(&MemDC, m_pLeftBmp,	0,			0, nLeft, h, RGB(255, 0, 0));
		DrawTransparentBitmap(&MemDC, m_pCursorBmp,	nCursorPos, (h-sz.cy)/2, sz.cx, sz.cy, RGB(255, 0, 0));

		dc.BitBlt(0, 0, w, h, &MemDC, 0, 0, SRCCOPY);

		MemDC.SelectObject(pOldBmp);
	}
}

void CMegaSlider::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	int nVal = GetScrollPos();
	int nMin = 0, nMax = 0;
	GetScrollRange(&nMin, &nMax);
	int nRange = nMax-nMin;

	CRect rc;
	GetClientRect(&rc);

	int nLeft = nVal*rc.Width() / nRange;
	CSize sz = m_pCursorBmp->GetBitmapDimension();

	CRect rcCursor(nLeft-sz.cx/2, rc.top, nLeft+sz.cx/2, rc.bottom);
	if(rcCursor.PtInRect(point))
	{
		SetCapture();
		m_bDrag = true;
	}
	else
	{
		SetScrollPos(point.x*nRange/rc.Width());
	}
}

void CMegaSlider::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if(m_bDrag)
	{
		ReleaseCapture();
		m_bDrag = false;
	}
}

void CMegaSlider::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if(m_bDrag)
	{
		int nVal = GetScrollPos();
		int nMin = 0, nMax = 0;
		GetScrollRange(&nMin, &nMax);
		int nRange = nMax-nMin;

		CRect rc;
		GetClientRect(&rc);

		int nLeft = nVal*rc.Width() / nRange;
		CSize sz = m_pCursorBmp->GetBitmapDimension();

		SetScrollPos(point.x*nRange/rc.Width());
	}
}

BOOL CMegaSlider::OnEraseBkgnd(CDC* pDC) 
{
	// TODO: Add your message handler code here and/or call default
	return FALSE;
}

